<template>
  <div class="skybox">
    <div class="title">
      <el-radio-group v-model="intensity">
        <el-radio-button value="0.5" @change="setLightIntensity(0.5)">暗</el-radio-button>
        <el-radio-button value="1.5" @change="setLightIntensity(1.5)">正常</el-radio-button>
        <el-radio-button value="2.5" @change="setLightIntensity(2.5)">亮</el-radio-button>
      </el-radio-group>
    </div>
    <div ref="refDom" class="model-view">
    </div>
  </div>
</template>

<script setup>
import {useTemplateRef} from 'vue'
import * as THREE from 'three'
import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls.js'
import Stats from 'three/examples/jsm/libs/stats.module.js'
import {GLTFLoader} from 'three/addons/loaders/GLTFLoader.js'
import * as SkeletonUtils from 'three/examples/jsm/utils/SkeletonUtils.js'

defineOptions({
  name: 'threejs'
})
const intensity = ref(0.5)
const refDom = useTemplateRef('refDom')
let DOM, scene, camera, renderer, controls, frameStats, ambientLight
const gltfLoader = new GLTFLoader()
onMounted(() => {
  DOM = refDom.value
  initScene()
  initCamera()
  initRender()
  initControls()
  initLight()
  initFrameStats()
  createGeometry()
  initHelpers()
  render()
})
// 初始化场景
const initScene = () => {
  scene = new THREE.Scene()
}
// 初始化相机
const initCamera = () => {
  camera = new THREE.PerspectiveCamera(30, refDom.value.clientWidth / refDom.value.clientHeight, 0.1, 1000)
  camera.position.set(10, 10, 10)
  camera.lookAt(0, 0, 0)
}
// 初始化渲染器
const initRender = () => {
  renderer = new THREE.WebGLRenderer({
    antialias: true, // 抗锯齿
    alpha: true//背景色透明
  })
  renderer.setPixelRatio(window.devicePixelRatio)
  renderer.toneMapping = THREE.ACESFilmicToneMapping
  renderer.toneMappingExposure = 1
  renderer.setSize(DOM.clientWidth, DOM.clientHeight)
  DOM.appendChild(renderer.domElement)
}
// 初始化控制器
const initControls = () => {
  controls = new OrbitControls(camera, renderer.domElement) // 鼠标控制
  controls.enableDamping = true // 设置阻尼
  controls.update()
}

const initHelpers = () => {
  scene.add(new THREE.AxesHelper(100)) // xyz轴辅助线
}
const initLight = () => {
  ambientLight = new THREE.AmbientLight(0xffffff, 1) // 环境光
  scene.add(ambientLight)
}
const setLightIntensity = (val) => {
  intensity.value = val
  ambientLight.intensity = val
}
// 创建性能监视器
const initFrameStats = () => {
  frameStats = new Stats()
  frameStats.setMode(0)// 设置监视器面板，传入面板id（0: fps, 1: ms, 2: mb）
  // 设置监视器位置
  frameStats.domElement.style.position = 'absolute'
  frameStats.domElement.style.left = '0px'
  frameStats.domElement.style.top = '0px'
  // 将监视器添加到页面中
  DOM.appendChild(frameStats.domElement)
}

const podiumGroup = new THREE.Group()
const createGeometry = () => {
  //创建一个长方体几何对象Geometry
  const geometry1 = new THREE.BoxGeometry(5, 1, 1)
  const geometry2 = new THREE.BoxGeometry(2, 1, 1)
  const geometry3 = new THREE.SphereGeometry(0.5)
//材质对象Material
  const material = new THREE.MeshPhongMaterial({
    color: 0x00ffff,
    shininess: 20, //高光部分的亮度，默认30
    specular: 0x444444 //高光部分的颜色
  })
  const meshBox1 = new THREE.Mesh(geometry1, material) //网格模型对象Mesh
  const meshBox2 = new THREE.Mesh(geometry2, material)
  const meshBox3 = new THREE.Mesh(geometry3, material)
  meshBox2.position.y = 0.8
  meshBox3.position.y = 1.5
  podiumGroup.add(meshBox1)
  podiumGroup.add(meshBox2)
  podiumGroup.add(meshBox3)
  scene.add(podiumGroup) //网格模型添加到场景中

  const directionalLight = new THREE.DirectionalLight(0xffffff, 2) // 平行光
  directionalLight.position.set(3, 5, 1)
  directionalLight.target = podiumGroup
  scene.add(directionalLight)

}

const render = () => {
  frameStats.update()// 更新帧数
  renderer.render(scene, camera)
  // geoGroup.rotateY(Math.PI / 180)
  requestAnimationFrame(render)
}
</script>

<style lang="scss" scoped>
.skybox {
  width: 100%;
  height: 100%;

  .title {
    height: 30px;
    line-height: 30px;
    margin-bottom: 10px;
  }

  .model-view {
    position: relative;
    width: 100%;
    height: calc(100% - 40px);
  }
}
</style>
